微软offer养成计之笔经分享

软软子的校招活动越来越丰富了,作为微软第一站姐表示无比欣慰!

这次的offer养成计也是微软给小朋友们一次熟悉笔面试流程的机会,于是毫不犹豫就上车了。

ps:本贴是在所有同学笔试结束后才发出来的,坚决保卫笔试的公正哦。希望为没参加的盆友们参考一下题目,以及期待和参加的盆友们一起探讨!
pps:有想投微软PM的兄弟姐妹们请联系我!可以一起准备哦 ღ( ´・ᴗ・` )

笔试介绍

  • 平台:Codility
  • 时长:130min,任选时间进入
  • 题量:3道题,个人感受是1 easy + 1 medium + 1 hard,难度均衡得挺好
  • 日期:2022年7月15日

笔试经验

  • 平常做leetcode时,我一直是白板做题。但是毕竟是笔试,IDE不用白不用^ ^,所以我都先在IDE中写好测试好,然后粘贴到codility中。不然我担心自己不小心按到codility的提交按钮sos
  • 我不了解面试官在筛选的时候,有多大比重会考虑做题速度(这个我打算后续咨询一下!)。但无论如何,我依然选择略牺牲速度来提高代码的优美性,能加的注释全都加得整整齐齐的。

题解分享

  • 以下仅为个人解法,如果代码有错误(最好不要qwq) or 有更优的解法,欢迎大家在评论区提出!
  • 我写python比较顺手,也欢迎大家提出其他语言的解法。

T1:气球走开!

  • 题目:
    • 给定字符串S,只由大写字母组成,每次移走一个BALLOON(不用在意字母顺序),问可以移走几个BALLOON
  • 限制:
    • S: [1, 2 x 10^5]
  • 思路:
    • 遍历字符串S,记录S中每个字母出现的次数。
    • 对于BALLOON中的每个字符,计算S中该字符的数目能够构成几个BALLOON
    • 根据木桶原理,取这些字符分别能构成BALLOON的个数的最小值,即为结果
  • 复杂度:
    • 时间复杂度:O(n)nS的长度
    • 空间复杂度:O(|∑|), 是字符集,本题为26个大写字母
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

from collections import defaultdict

def solution(S):
    # Time complexity: O(n), where n represents the length of S
    # Space complexity: O(|Sigma|), where Sigma is 26

    # step1: build a dict of 'balloon'
    word = defaultdict(int)
    word['B'] = 1
    word['A'] = 1
    word['L'] = 2
    word['O'] = 2
    word['N'] = 1

    # step2: build another dict of the frequency of all the characters in S
    counter = defaultdict(int)
    for ch in S:
        counter[ch] += 1

    # step3: traverse all the characters, calculate how much balloon can construct only considering this character
    # and the min value will be the answer
    min_num = float('inf')
    for ch in word:
        min_num = min(min_num, counter[ch] // word[ch])
        # print(ch, counter[ch], word[ch], counter[ch] // word[ch])
    return min_num

S = 'BAONXXOLL'
S = 'BAOOLLNNOLOLGBAX'
S = 'QAWABAWONL'
S = 'ONLABLABLOON'
S = 'BALLOON'
S = ''
res = solution(S)
print(res)

T2:两只跳跳蛙

  • 题目:
    • 给定一排荷叶blocks[],值代表荷叶的高度。
    • 青蛙从荷叶i跳到荷叶j的条件是:i j相邻,且 blocks[j] >= blocks[i]
    • 对于荷叶iji <= j),两片荷叶的距离为j - i + 1
    • 请问:有两只青蛙初始站在同一片荷叶上,它们俩可以按照上述规则分别跳跃,求两只青蛙的可能的最远距离。
  • 举例:
    • blocks = [1, 5, 5, 2, 6],最好的情况是两只青蛙初始化站在第3片荷叶上(即高度为2),一只向左跳2次,一只向右跳1次,最终的距离是2+1+1=4
  • 限制:
    • N <= 2*10^5
    • blocks[i] <= 1*10^9
  • 思路:
    • 计算以i为起点,向左和向右分别能跳多少步,两者相加再加1就是从该点初始的最远距离。
    • 所有的最远距离取最大值即为结果。
  • 复杂度:
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)
# Remember, all submissions are being checked for plagiarism.
# Your recruiter will be informed in case suspicious activity is detected.

# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

def solution(blocks):
    # Task: find the longest possible distance between two frogs
    # Limit: N <= 2*10^5, blocks[i] <= 1*10^9

    # Method: starting from each block[i], find the longest steps jumping to the left, and the longest steps to the right.
    #         Add them together and add one. The longest will be the answer
    # Time Complexity: O(n)
    # Space Complexity: O(n). I'm not sure if there exists a method with more efficient space complexity.

    n = len(blocks)

    # step1: find the longest steps jumping to the left
    # `jump_to_left[i]` means how many steps the frog can jump to the left
    jump_to_left = [0] * n
    sum_ = 0
    for i in range(1, n):
        # the current block is no higher than the left one
        if blocks[i] <= blocks[i - 1]:
            # can jump one more block
            sum_ += 1
            jump_to_left[i] = sum_
        else:
            sum_ = 0

    # step2: find the longest steps jumping to the right
    # `jump_to_right[i]` means how many steps the frog can jump to the right
    jump_to_right = [0] * n
    sum_ = 0
    for i in range(n-2, -1, -1):
        # the current block is no higher than the right one
        if blocks[i] <= blocks[i + 1]:
            # can jump one more block
            sum_ += 1
            jump_to_right[i] = sum_
        else:
            sum_ = 0

    # step3: find the longest distance between the two frogs
    res = 0
    for i in range(n):
        res = max(res, jump_to_left[i] + jump_to_right[i] + 1)

    return res


blocks = [2, 6, 8, 5]
# blocks = [1, 5, 5, 2, 6]
# blocks = [1, 1]
# blocks = [1]
# blocks = [1, 2, 3]
# blocks = [3, 4, 1, 6, 5, 2, 7]


res = solution(blocks)
print(res)

T3:三点共线

  • 题目:
    • 给定二维平面上的点坐标的列表AA[i].x表示第i个点的横坐标,A[i].y表示第i个点的纵坐标。A中的点没有重合
    • 求这些点中,有多少个三元组,满足这三点共线。
    • 如果答案超过10**8,返回-1。
  • 举例:
    • 图片说明
    • 假设点集如上图所示,结果将返回6,代表有6个三元组。它们分别是
      • (A[0], A[1], A[2])
      • (A[0], A[1], A[3])
      • (A[0], A[2], A[3])
      • (A[1], A[2], A[3])
      • (A[2], A[4], A[5])
      • (A[3], A[5], A[6])
  • 限制:
    • n <= 10^3, 意味着不能用O(n^3)的暴力法
    • A.x, A.y < 10^4
  • 思路:
    • 假设结果为res。对于每个点i
      • 建立哈希表slopes,记录每个斜率出现的次数
      • 遍历点jj > i),求出ij的斜率,设为slope,那么,slopes[slope]应该加一。
      • 遍历所有的斜率,设某斜率slope对应num个点,那么包含点i在内的斜率为slope的三元组数目为C(num, 2) = num * (num - 1) // 2res加上该值即可。
  • 难点:
    • 斜率涉及到小数精度问题,所以这里slopes中不存真正的斜率,而是存坐标差。具体而言,计算dxdy,然后求最大公约数进行约分,以字符串的形式存到slopes中。
    • 可以类比leetcode 149. 直线上最多的点数的。
  • 复杂度:
    • 时间复杂度:O(n^2 * log(m)), nA的长度, m是两点的最大坐标差值
    • 空间复杂度:O(n)
# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

# from extratypes import Point2D  # library with types used in the task

class Point2d:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def get_A(li):
    res = []
    for x, y in li:
        res.append(Point2d(x, y))
    return res


from collections import defaultdict

# find the greatest common divisor
def gcd(x, y):
    if y == 0:
        return x
    else:
        return gcd(y, x % y)

def solution(A):
    # Task: find how many triplets that can form a line
    # Limit: (1) n <= 10^3, (2) A.x, A.y < 10^4, (4) A is distinct

    # Method: Hash Map, using gcd to record slopes
    # Time Complexity: O(n^2 * log(m)), where n is len(A), m is max difference of x coordinates and y coordinates
    # Space Complxity: O(n)

    n = len(A)
    res = 0
    # traverse the first point A[i]
    for i in range(n - 1):
        x1, y1 = A[i].x, A[i].y
        # 'slopes' format is like {slope1: num1, slope2: num2, ...}
        slopes = defaultdict(int)
        # find the slopes between A[i] and all other later points
        for j in range(i + 1, n):
            x2, y2 = A[j].x, A[j].y
            dx, dy = x2 - x1, y2 - y1
            # find the most simple form
            g = gcd(dx, dy)
            if g != 0:
                dx //= g
                dy //= g
            # record this slope
            slopes["{}/{}".format(dy, dx)] += 1

        # The result would add C(n, 2) = n * (n-1) // 2
        for slope in slopes:
            res += slopes[slope] * (slopes[slope] - 1) // 2
    # Do not exceed the limit
    if res > 10 ** 8:
        return -1
    return res

li = [[1, 1], [0, 0], [2, 2], [3, 2], [4, 2], [3, 3], [5, 1], [4, 4]]
res = solution(get_A(li))
print(res)

OK,以上就是本次笔经。笔试结束后就收到收集意向的邮件了,果断选了PM!历尽千帆,还是做PM最快乐。祝愿有面试机会 & 面试顺利!

#微软##校招##笔经#
全部评论
太牛了,第三题想到了斜率但是没想到用哈希,直接交了o3暴力,寄了
2 回复 分享
发布于 2022-07-16 05:42
ide不用白不用(„ಡωಡ„)栓Q
1 回复 分享
发布于 2022-08-08 22:50
同学,祝愿你心想事成! 同时,我也介绍下我们荣耀公司,团队氛围很nice,对新人有专门的培养导师,也欢迎你投递,我的荣耀内推码: bzctoa, 荣耀公司不乏清北复旦上交大西交大中科院等国内高校,也有国外留学生等,聚五湖四海之英才,欢迎大家投递荣耀公司
1 回复 分享
发布于 2022-08-04 12:49
产品都这么强,我开发都不会
1 回复 分享
发布于 2022-07-18 23:50
最后一道题解法一样但是死活没调对 寄了😂
1 回复 分享
发布于 2022-07-16 00:29
歌尔精英计划~ 薪资待遇对标互联网 硕士:③③~④⑨W 博士:④③~⑤⑨W 不用担心毕业问题 双导师培养 五年公司中高层 岗位:北京上海青岛南京潍坊 内推码:cssobb 内推码:cssobb 内推码:cssobb 已经内推60多人 抓紧上车,抢先拿到offer 方式一:直接扫内推二维码投递 方式二:点击链接投递的时候会有输入内推码一栏,扫码投递 记得输入内推码哈~ 记得输入内推码哈~ 记得输入内推码哈~ 为师弟师妹查看进度,答疑解惑哈~ 🉑私信沟通呀 投递链接:https://mp.weixin.qq.com/s/xusid68IfiPwmXoiD4R2UQ
点赞 回复 分享
发布于 2022-07-25 22:19
请问收到模拟面试通知了么,不知道发了没还是凉了
点赞 回复 分享
发布于 2022-07-19 13:48
感谢楼主的分享,话说这个模拟面试通知有同学收到吗?
点赞 回复 分享
发布于 2022-07-18 15:56
借楼贴一下C++ Task1 https://pastebin.com/dfE18WUL Task2 https://pastebin.com/V5mYWken Task3 没有Task3,因为我没想到点了Task3的提交后就直接全部提交退出答题页面了,没来得及复制😭
点赞 回复 分享
发布于 2022-07-16 21:52
他这个是提前批么
点赞 回复 分享
发布于 2022-07-16 11:36
可惜了,下周时间冲突没时间搞模拟面试,只得含泪放弃。还有就是为啥我感觉我交卷之前模拟面试意向的邮件就来了😂
点赞 回复 分享
发布于 2022-07-16 09:20
太强了
点赞 回复 分享
发布于 2022-07-16 00:25

相关推荐

吴offer选手:学到了,下次面试也放张纸在电脑上,不然老是忘记要说哪几个点
点赞 评论 收藏
分享
评论
24
104
分享

创作者周榜

更多
牛客网
牛客企业服务