本篇介绍阿里3月25日的笔试题以及解法。
前提概要
今年阿里笔试是内部确认必须要经过的流程,可见还是很重要的。使用的是牛客网的平台,自己写输入输出以及功能模块,两道编程题,共1h。
编程题
- 给一个m*n的矩阵,m固定为3,n任意;每列取一个值,求出最小的
∑
i
=
2
n
∣
a
i
−
a
i
−
1
∣
\sum\limits_{i=2}^{n}|a_{i}-a_{i-1}|
i=2∑n∣ai−ai−1∣。
输入示例(有n和data):
5
5 10 5 4 4
1 7 8 4 0
3 4 9 0 3
输出:
5
class Solution:
def fun(self, matrix, n) -> int:
rows = 3
cols = n
dp = [[0]*cols for _ in range(rows)]
# 初始条件
for i in range(rows):
dp[i][0]=0
# 状态转移
for j in range(1,cols):
for i in range(rows):
tmp1 = abs(matrix[i][j]-matrix[0][j-1])
tmp2 = abs(matrix[i][j]-matrix[1][j-1])
tmp3 = abs(matrix[i][j]-matrix[2][j-1])
dp[i][j] = min(dp[0][j-1]+tmp1,dp[1][j-1]+tmp2,dp[2][j-1]+tmp3)
# print(dp)
return min(dp[0][cols-1],dp[1][cols-1],dp[2][cols-1])
if __name__ == '__main__':
n = int(input())
tmp = 3
data = []
while tmp>0:
line = input()
line = line.split(' ')
data.append(list(map(int,line)))
tmp-=1
solution = Solution()
res = solution.fun(data,n)
print(res)
第一题用到的是动态规划,上面代码时间复杂度是 O ( M ∗ N ) O(M*N) O(M∗N),空间复杂度是 O ( M ∗ N ) O(M*N) O(M∗N)。由于状态转移时只关系到前一列的dp与当前列,所以可把空间复杂度降到 O ( M ) O(M) O(M)。
- 给一个m*n的数组A,其中每行每列都是等差数列,但是其中
A
i
j
=
0
A_{ij}=0
Aij=0表示不知道该处的值是多少,要求我们去找出能判断出值的并填进去,然后给q个坐标,返回其位置上的值,判断不出来的输出Unknown。
输入示例(m、n、q还有data以及q个坐标):
2 3 6
1 0 3
0 0 0
1 1
1 2
1 3
2 1
2 2
2 3
输出:
1
2
3
Unknown
Unknown
Unknown
class Solution:
def fun(self, matrix, m, n) -> int:
rows = m
cols = n
# 每行每列只要能找到两个元素,就能确定这行这列所有元素
# 每行
import collections
row_record = collections.defaultdict(list) #能够判断出该行所有数据所需的数据
row_set = set() #该行的0是被判断出来的,不是unknown
for i in range(rows):
for j in range(cols):
if matrix[i][j]!=0:
row_record[i].append([j,matrix[i][j]])
if len(row_record[i])==2:
break
# 每行进行补充
for i in range(rows):
if len(row_record[i])==2:
row_set.add(i)
tmp1,tmp2 = row_record[i][0],row_record[i][1]
loc1,loc2 = tmp1[0],tmp2[0]
val1,val2 = tmp1[1],tmp2[1]
step = (val2-val1)/(loc2-loc1)
# 第一个loc向左补充
for j in range(loc1-1,-1,-1):
matrix[i][j]=matrix[i][j+1]-step
# 向右补充
for j in range(loc1+1,cols):
matrix[i][j]=matrix[i][j-1]+step
# 每列
col_record = collections.defaultdict(list) #能够判断出该行所有数据所需的数据
col_set = set() # 该列的0是被判断出来的,不是unknown
for j in range(cols):
for i in range(rows):
if matrix[i][j] != 0:
col_record[j].append([i, matrix[i][j]])
if len(col_record[j]) == 2:
break
# 每列进行补充
for j in range(cols):
if len(col_record[j]) == 2:
col_set.add(j)
tmp1, tmp2 = col_record[j][0], col_record[j][1]
loc1, loc2 = tmp1[0], tmp2[0]
val1, val2 = tmp1[1], tmp2[1]
step = (val2 - val1) / (loc2 - loc1)
# 第一个loc向上补充
for i in range(loc1 - 1, -1, -1):
matrix[i][j] = matrix[i+1][j] - step
# 向下补充
for i in range(loc1 + 1, rows):
matrix[i][j] = matrix[i-1][j] + step
return row_set,col_set
if __name__ == '__main__':
line = input()
line = line.split(' ')
m,n,q = int(line[0]),int(line[1]),int(line[2])
tmp = m
data = []
while tmp>0:
line = input()
line = line.split(' ')
data.append(list(map(int,line)))
tmp-=1
loc = []
tmp = q
while tmp>0:
line = input()
line = line.split(' ')
loc.append(list(map(int, line)))
tmp -= 1
solution = Solution()
row_set,col_set = solution.fun(data,m,n)
for val in loc:
if (int(data[val[0]-1][val[1]-1])==0) and (val[0]-1 not in row_set) and (val[1]-1 not in col_set):
print("Unknown")
else:
print(int(data[val[0]-1][val[1]-1]))
第二题就直接面对测试用例编程即可,就是一般的那种模拟题。
结语
就个人感觉,今天的笔试题并不难,要注意的点应该是事先要熟悉输入怎么写,用python编程的小伙伴一般不经常用input(),所以遇到一行用空格隔开的元素,如何分开等等,都是值得注意的问题。就牛客网上的反馈,还是有不少同学吃了这个亏!
感觉不错,就请素质三连哈-v-