今天终于有了一次面试,尽管结果多半是凉了,但还好有了第一次面试邀请,这也算是对我简历上的内容的一个认可。
今天下午面的是一家外包,毕竟能力差没办法,能有进正规公司的机会肯定就进正规公司了,但即使是外包公司的面试,对我来说也是非常吃力的,如果100%是满分,那我只能给自己打30%。语言基础和框架部分我就不提了,毕竟都是老生常谈的基本能力。这里我分享面试中遇到的几个基础的算法题,希望能对大家有所帮助。
1 .二维数组由0和1组成,求数组里面的特殊字符个数,特殊字符的定义是:一个数是1,它的横行和竖行全是0,这个1就算是特殊字符。 比如: 00001 10000 01000 00100 00010 得出5
这题我当初写了个O(n^3)的,写了跟没写一样,但是也没办法了。但是我到现在也没想到好的思路,哪位会的大哥教我怎么写啊。
随后按照群里大佬的思路,写了一个O(n^2)的:
public static int findSpecial ( int [ ] [ ] arr) {
int result = 0 ;
int [ ] columnNum = new int [ arr. length] ;
int [ ] countPerColumn = new int [ arr[ 0 ] . length] ;
for ( int i= 0 ; i< arr. length; i++ ) {
int num = 0 ;
int j = 0 ;
columnNum[ i] = - 1 ;
for ( j = 0 ; j < arr[ 0 ] . length; j++ ) {
if ( arr[ i] [ j] == 1 )
num++ ;
}
if ( num == 1 )
columnNum[ i] = j- 1 ;
}
for ( int i= 0 ; i< arr[ 0 ] . length; i++ ) {
int num = 0 ;
for ( int j = 0 ; j < arr. length; j++ ) {
if ( arr[ j] [ i] == 1 )
num++ ;
}
countPerColumn[ i] = num;
}
for ( int i= 0 ; i< arr. length; i++ ) {
if ( columnNum[ i] != - 1 && countPerColumn[ columnNum[ i] ] == 1 )
result++ ;
}
return result;
}
思路就是定义两个数组,一个数组columnNum大小是总行数,一个数组countPerColumn大小是总列数。一行一行遍历数组,只有当当前行有且只有一个1时在columnNum[行数]记录这个1的列数,其余为-1;countPerColumn数组记录每个列的1有多少个。最后遍历数组a1,如果不等于-1且查找countPerColumn数组相应的列只有一个1,则result++
2 . 二叉树的中序遍历
很简单的一题,属于每个人都要会的,我是觉得二叉树除了删除难点,知道个大概就好,其他的都要掌握
public void traverse ( ) {
traverse ( root) ;
}
private void traverse ( TreeNode curr) {
if ( curr== null)
return ;
traverse ( curr. left) ;
System. out. print ( curr. value+ " " ) ;
traverse ( curr. right) ;
}
3.求两个字符串是否相同,这个字符串包含小写字母和<,<代表把前面一个字符删除,求经过<删除过的两个字符串的是否相同
这题我当初想的是压字符到栈里面,然后遇到多少个<就弹出多少个字符,最后用StringBuilder接收处理一下,而且时间复杂度为O(n),其实感觉还行,谁知面试官说只能用一个额外的存储...我就没办法了,谁知道还能怎么优化优化啊?先把我当时的贴出来吧:
public static boolean compareString ( String s1, String s2) {
return dealWithString ( s1) . equals ( dealWithString ( s2) ) ;
}
private static String dealWithString ( String str) {
Stack< Character> s = new Stack < Character> ( ) ;
StringBuilder sb = new StringBuilder ( ) ;
for ( int n= 0 ; n< str. length ( ) ; n++ ) {
if ( str. charAt ( n) == '<' && ! s. empty ( ) )
s. pop ( ) ;
else
s. push ( str. charAt ( n) ) ;
}
while ( ! s. empty ( ) ) {
sb. append ( s. pop ( ) ) ;
}
return sb. toString ( ) ;
}
4 .一个二维数组由0和1组成,如果数组里面有两个或多个1横向或纵向相连,就算是一个岛屿,四周被水包围。求其中最大的岛屿面积。
这题我当初想炸了也不会...后来经过提醒用DFS,我有点递归的思路,但还是不会,后来看了在网络上找到的解答,才一下子明白过来,用两个循环来遍历某个方格,从每个方格开始递归调用周围的,来计算它的1的个数,并且新创了一个数组来判断这个方格有没有被执行过。我当时有这个思路,但是怎么也写不出来。
public static int findMaxIslandArea ( int [ ] [ ] arr) {
boolean [ ] [ ] seen = new boolean [ arr. length] [ arr[ 0 ] . length] ;
int ans = 0 ;
for ( int r = 0 ; r < arr. length; r++ ) {
for ( int c = 0 ; c < arr[ 0 ] . length; c++ ) {
ans = Math. max ( ans, area ( arr, seen, r, c) ) ;
}
}
return ans;
}
private static int area ( int [ ] [ ] arr, boolean [ ] [ ] seen, int r , int c) {
if ( r < 0 || r >= arr. length || c < 0 || c >= arr[ 0 ] . length ||
seen[ r] [ c] || arr[ r] [ c] == 0 )
return 0 ;
seen[ r] [ c] = true ;
return 1 + area ( arr, seen, r+ 1 , c) + area ( arr, seen, r- 1 , c)
+ area ( arr, seen, r, c+ 1 ) + area ( arr, seen, r, c- 1 ) ;
}
只能说路还很长,还有很多东西要学啊...