[Alibaba] 校招二面面经

项目

先问了简历上面的项目,着重问了一个和本校研究生合作的一个NLP课题,因为是用深度学习做的,问了一些深度学习的基本知识,和自己对深度学习的理解。

然后问了一下我在项目中起的作用,我提到了通过复现其他paper来比较实验效果,然后面试官让我举一个复现论文的例子,我就给他讲了一个机器学习的例子,从word embedding到word2vec再到训练和测试过程,method方面我提到了朴素贝叶斯分类和Logistic回归。

然后面试官又让我讲讲对朴素贝叶斯分类和Logistic回归的理解。我就从算法的主要思想讲起,讲到了高斯分布的假设和最大似然估计法,随后又讲了如何从贝叶斯公式推出Logistic回归的公式,两个算法的统一性和差异性等等。

这部分大概面了二十分钟,我尽量把自己知道的每一个细节都讲清楚了,最后从情绪反馈上感觉面试官还是比较满意的。


算法

主要问了两个题

第一题

第一题比较简单,如何快速求出第 K K K大的数,满足其质因子只由3,5,7组成。

思路

这道题几乎是零思考秒杀了,中心思想是对 K K K进行三进制分解,随后三进制的三位0,1,2分别映射为3,5,7
按位加权计算后即可。


第二题

第二题稍微难了一点:
给定四十亿个无符号整型,生成一个没有出现在这四十亿个数里面的一个整数。

思路

首先一个显然思路是考虑二进制位。
从高位到低位枚举,比较当前位为1的整数个数和当前位为0的整数个数。
如果其中一个小,说明其中存在缺失的数
故直接循环地取即可。
时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度 O ( 1 ) O(1) O(1)

然后考虑如何空间换时间
一个更直观的思路是直接桶排序
即定义一个非常大的数组 v i s vis vis

遍历每个数,假如当前这个数为 x x x,则 v i s [ x ] = 1 vis[x] = 1 vis[x]=1
最后再遍历数组中的每一位 i d id id
v i s [ i d ] = 0 vis[id] = 0 vis[id]=0
则输出 i d id id即为所求
时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( n ) O(n) O(n)


这两个思路我都答到了,但面试官继续刁难了我qwq
如果我的空间只有 100 M 100M 100M,同时保证时间复杂度为 O ( n ) O(n) O(n)的情况下,如何提出一个更好的算法?

中间至少有3分钟我都在往位运算如异或等方向思考
但越想越复杂
最后面试官提示可以考虑分块
又想了一分钟后说出了最终的正解。

首先算一下,如果空间复杂度为 O ( n ) O(n) O(n)的情况下需要多少内存:(假设数组类型为 b o o l bool bool)
2 32 ∗ 1 B = 4 G B 2^{32} * 1B = 4GB 2321B=4GB
而如果要用 100 M 100M 100M的空间保存,则需要分成的块数为:
4 G B / 100 M ≈ 2 12 / 2 6 = 2 6 = 64 4GB/100M \approx 2^{12}/2^{6} = 2^6 = 64 4GB/100M212/26=26=64
而对于无符号整型,取值范围为: 0 0 0 ~ 2 32 − 1 2^{32}-1 2321
故每一块的长度为:
2 32 / 2 6 = 2 26 2^{32}/2^{6} =2^{26} 232/26=226

大体解题过程如下:
首先第一次遍历将每个数映射到相应的块
开一个计数器数组cnt[64]
对于当前遍历的数 x x x,令 c n t [ x / 2 26 ] cnt[x/2^{26}] cnt[x/226]++
然后找到其中某个块 k k k,满足 c n t [ k ] &lt; 2 26 cnt[k] &lt; 2^{26} cnt[k]<226,则说明块 k k k存在缺失值。

随后再开一个 b o o l bool bool数组 v i s [ 2 26 ] vis[2^{26}] vis[226],占内存 64 M B 64MB 64MB
第二次遍历每一个数
对于当前遍历的数 x x x,如果 x / 2 26 = = k x/2^{26} == k x/226==k
则令 v i s [ x − k ∗ 2 26 ] = 1 vis[x-k*2^{26}]=1 vis[xk226]=1
最后遍历 v i s vis vis数组的每一位
找到值为0的某一位 i d id id
则最终答案为: i d + k ∗ 2 26 id + k*2^{26} id+k226

此题最终就答完了(虽然思路很清楚,但感觉我面试答得很模糊…


Coding

Coding有两道题

第一题

找到最大连续子序列的和
这种送分题5行代码就秒杀了…

第二题

Write a program to find the longest word made of other words in a list of words

input : abc, def, gh, aldfldjldjf, abcdef, defgh
output : abcdef

想到了两种算法 ,先都给面试官口胡了一遍
问面试官需要我实现哪一种,还是全部实现
然后他让我实现动态规划的解法

思路很简单就不详细解释了

最后的代码如下:

map<string> mp;

bool cmp(string& x, string& y){
	return x.lenth() < y.lenth();
}

string getLongestWord(vector<string> wordList){
	mp.clear();	
    sort(wordList.begin(), wordList.end(), cmp);
	int n = wordList.size();
  	for (int i = 0; i < n; i++) {
    	mp[wordList[i]] = 1; 
    }
  	
  	string ans = "";
  	for (int i = 0; i < n; i++) {
    	int len = wordList[i].length();
      	bool flag = 0;
      	for (int j = 1; j < len; j++) {
        	string sub1 = wordList[i].substr(0, j);
          	string sub2 = wordList[i].substr(j, len - j);
          	if (mp[sub1] && mp[sub2]) {
            	flag = 1;
              	break;
            }
        }
    	if (flag) {
        	if (len > ans.length()) {
            	ans = wordList[i];
            }
        }
    }
  	return ans;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值