阿里春招之旅(六)

本篇介绍阿里3月25日的笔试题以及解法。

前提概要
今年阿里笔试是内部确认必须要经过的流程,可见还是很重要的。使用的是牛客网的平台,自己写输入输出以及功能模块,两道编程题,共1h

编程题

  1. 给一个m*n的矩阵,m固定为3,n任意;每列取一个值,求出最小的 ∑ i = 2 n ∣ a i − a i − 1 ∣ \sum\limits_{i=2}^{n}|a_{i}-a_{i-1}| i=2naiai1
    输入示例(有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(MN),空间复杂度是 O ( M ∗ N ) O(M*N) O(MN)。由于状态转移时只关系到前一列的dp与当前列,所以可把空间复杂度降到 O ( M ) O(M) O(M)

  1. 给一个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-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值