完整的Python代码在我的Github上可用。使用Python编程是任何数据相关面试的必备技能和准备领域!有四种类型的编程问题,包括数据结构和算法、机器学习算法、数学和统计以及数据操作(请参阅EmmaDing@Airbnb的精彩文章)。我在相关文章中介绍了有关数据操作和字符串提取的主题。在今天的帖子中,我将重点关注数学和统计学,并现场编写由一些最大的科技公司(尤其是FAANG)提出的五个Python编程问题。此类问题为您提供业务设置,并通过模拟要求统计解决方案。问题一:谁先赢?MicrosoftAmy和Brad轮流掷一个漂亮的六角骰子。谁先掷出“6”,谁就赢得了比赛。艾米先滚。艾米获胜的概率是多少?(1)思路这是一个核心的模拟题,没有比模拟大量的过程,检验Amy获胜概率更好的办法了。艾米先滚。如果结果是6,则游戏结束,艾米获胜。否则,Brad失败,如果是6,则游戏获胜。如果没有,回到艾米。重复该过程,直到有人以6结束游戏。这里的关键是理解逻辑流程:谁在什么情况下获胜。如果Amy得到6,Brad是否必须掷球?不。(2)问题解决importnumpyasnpdefwho_won(die,size):A_count=0#initializeA_countB_count=0#initializeB_countforiinrange(size):#createaniterationA_6=np.random.choice(die)#rollthefairdiceandchoosearandomvaluefrom0to6ifA_6==6:#ifArolls+add=1.A_count#aside-noteforPythonbeginners:完整的表达式是"A_countA_count=A_count+1"else:#iftheaboveifconditiondoesnotfullfillB_6=np.random.choice(die)#then,it'sB'sturntorollthedice,whichsarandomchoicefrom0to6.ifB_6==6:#ifBroll+saB,B_countadds=1。1returnA_count/(A_count+B_count)#returnthetotalnumberofcasesthatAwondividedbythecombinednumberofAandBwonaka.returnthetotalnumberofcasesthatAwondividedthecombinednumberofAandBwonaka.theresultistheprobabilitythatAmywins.1returnA_count/(A_count+B_count)#returnthetotalnumberofcasesthatAwondividedbythecombinednumberofAandBwonaka.theresultistheprobabilitythatAmywins.检查第11行:A_6是Amy的数据分布,如果她的数据是6,则计数+1。否则,布拉德可以掷骰子。最后(第25行),最终结果应该是Amy获胜的次数除以Amy和Brad获胜的总次数。一个常见的错误是将A_count除以模拟总数。这是不正确的,因为当Amy和Brad都未能掷出6时会有迭代。让我们测试上面的算法。np.random.seed(123)die=[1,2,3,4,5,6]size=10000who_won(die,size)viewraw0.531271015467384事实证明,Amy先于Brad才开始滚动赢得这场比赛。艾米有53%的机会在10,000次模拟中获胜。>PhotobyjohnvicenteonUnsplash问题2:每个主要公司的最大数量为69-给定一个仅由数字6和9组成的正整数num。-返回最多改变一位数字可以获得的最大数字(6变成9,9变成6)。https://leetcode.com/problems/maximum-69-number/(1)思路给定一个正整数,只有一种方法可以增加值,即“6”变成“9”,反之则不行大约。另外,我们必须改变最左边的6个;否则,它不是最大数量。例如,我们必须将“6996”改为“9996”,而不是“6999”。我想出了这个问题的几种变体:你可以改一次,也可以全部改成6。(2)解决方案1:替换一次#replaceoncedefmax_69_once(num):returnint(str(num).replace('6','9',1))#testcasenum=966666669max_69_once(num)996666669在第3行中,我们将整数转换为字符串,然后将第一个“6”替换为“9”;使用int()将其作为整数返回。(3)方案二:全部替换defmax_69_all(num):k=len(str(num))returnint(str(num).replace('6','9',k))#testcasenum=966666669max_69_all(num)999999999对于第二种情况,我们不必指定k,因为replace()方法默认会更改所有合适的值。我出于教学目的指定了k值。这个问题的另一个变体是替换前两个或三个“6”以得到最大的数字。>照片由AlessandroCapuzzi在Unsplash上拍摄问题3:有效的完全正方形。Facebook-给定一个正整数num,编写一个函数,如果num是一个完全平方数,则返回True;否则返回False。-后续:不要使用任何内置的库函数(如sqrt)。https://leetcode.com/problems/valid-perfect-square/(1)思路这很简单:检查一个正整数是否有完全平方根,如果有则返回True,这可以分两次完成脚步。求平方根。检查它是否是完美的平方根。棘手的部分是我们必须使用内置库(例如,数学、Numpy)来计算平方根,这在LeetCode上是一个简单的问题。如果我们不能使用这些库,那么它就变成了一个更具挑战性和重复出现的问题,这是LeetCode中的一个中级问题。(2)方案一:内置库importmathdefvalid_perfect_square(num):returnint(math.sqrt(num))**2==num#theint()方法只返回整数部分,忽略小数部分。#forfectsquares,shouldbenodecimalpart.Theequationsshouldthhold.#testcasevalid_perfect_square)算法easily(16Passedthetestcase.需要注意的是,我们需要使用int()方法只获取平方根的整数部分,忽略任何小数部分。对于一个完美的平方,它不会有任何区别,所以等式成立。对于非完全平方,等式将不成立并返回False。(特别感谢韩琦指出bug!)解决方案2:没有内置库和二进制搜索#1findthesqurerootofnum#2checkifitisaperfectsquarenumber#solution:nobuilt-inlibrary&binarysearchdefvalid_perfect_square(num):ifnum<2:returnTrueleft,right=2,num//2#createtwopointers:leftandrightwhileleft<=right:#whilelooptoconstantlyupdateleftandrightx=left+(right-left)//2#takeawildguessandtreatx作为起点xx_squared=x*x#calculatethesquaredvalueofxifx_squared==num:#usethefollowing'if-else'statementtoconstantlyupdatex_squared.returnTrue#numifthereareTruif:returnTrue#ifthereareTruif:returnTrue#ifx_squaredissmallerthannum,leftincreasesby1left=x+1else:#ifx_squaredisbigger,rightdecreasesby1right=x-1returnFalse#thewhileloopshouldcontinueloopinguntilleleftandrightconvergeandnocommonvalueobtained#testcasevalid_perfect_square(16)二进制搜索如果没有库允许。LeetCode包含详细解释(此处),我还发表了另一篇关于该主题的文章(此处)。简而言之,我们创建了两个指针left和right,并将这两个数的平均值与原始数进行比较:如果小于该数,则增加该值;否则,我们将增加值。如果它更大,我们减少它;或者,如果它们匹配,则返回True。这些条件将在while循环中自动检查。#Problem4:阶乘尾随零。Bloomberg给定一个整数n,返回n中的尾随零!追问:你能写一个对数时间复杂度的解决方案吗?https://leetcode.com/problems/factorial-trailing-zeroes/(1)思路这道题分两步:计算n阶乘n!计算尾随零的数量第一步,我们使用while循环遍历n个阶乘并停止循环直到1。对于第二步,事情变得有点棘手。该问题要求尾随零而不是总零。这是一个很大的不同。8!是40,320,它有2个零,但只有1个尾随零。我们在计算时必须格外小心。我想出了两个解决方案。(2)方案一:向后读取字符串#1calculaten!#2calculatethenumberoftrailingzerosdeffactorial_zeros(n):product=nwhile>1:#iterativelycalculatetheproductproduct*=(n-1)n-=1count=0foriinstr(product)[::-1]:#calculatethenumberoftrailingzerosifi=='0':count+=1else:breakreturncountfactorial_zeros(20)计算乘积的第一部分是不言自明的。第二部分,我们使用str()方法将乘积转为字符串,然后倒着读:如果数字是0,我们就把count加1;否则为0。否则,我们将打破循环。break命令在这里至关重要。如前所述,上面的函数在没有中断命令的情况下统计零的总数。(3)方案二:while循环deffactorial_zeros(n):product=nwhile>1:#step1:iterativelycalculatetheproductproduct*=(n-1)n-=1count=0whileproduct%10==0:#step2:calculatethenumberoftrainingzerosproductproduct=product/10count+=1returncount第一部分与方案一相同,唯一不同的是我们使用了一个while循环来计算尾部数字:乘积除以10,最后一位必须为0。所以我们使用while循环不断更新while循环,直到条件不成立。顺便说一句,解决方案2是我最喜欢的计算零的方法。>JamieFenn拍摄的Unsplash问题5:完美数,亚马逊理想数是一个正整数,等于其正因子之和,不包括数字本身。整数x的约数是将x整除的整数。给定一个整数n,如果n是一个完美的数字,则返回true,否则返回false。https://leetcode.com/problems/perfect-number/(1)思路这道题可以分为三步:找出积极因素并计算总和来决定:完美与否第二步和第三步不言自明是的,不超过一层。然而,棘手的部分是找到正除数。为此,我们可以采用蛮力方法并遍历从1到整数的整个序列。理论上,它应该适用于小整数,但如果我们对大数运行它,它会超过时间限制。时间效率不是很高。(2)解法一:暴力#1.findthepositivedivisors#2.calculatethesum#3.perfectornotdefperfect_number(num):divisors=[]foriinrange(1,num):ifnum%i==0:divisors.append(i)ifsum(divisors)==num:returnTrueelse:returnFalse#testcase1perfect_number(2)此方法不适用于较大的值。您的面试官可能会要求更有效的解决方案。(3)方案二:sqrt(n)#solution2:sqrt(n)defperfect_number(num):ifnum<=1:returnFalsedivisors=set([1])foriinrange(2,int(num**0.5)+1):#from2tonum**0.5ifnum%i==0:divisors.add(i)divisors.add(num//i)returnsum(divisors)==num要找到它的除数,我们不必检查它的值最大的整数。例如,要找到100的除数,我们不必检查从1到100的数字。相反,我们只需要检查100的平方根即10,所有其他可用值都已包括在内。这是一个最优算法,可以为我们节省很多时间。我的Github上提供了完整的Python代码。https://github.com/LeihuaYe/Python_LeetCode_Coding总结在做了几十次“实践”编码之后,最大的收获是理解问题并将其分解为可操作的组件。在这些可操作的部分中,总有一个步骤会绊倒求职者。诸如“不能使用内置函数/库”之类的限制。关键是按部就班地编写你的自定义函数,在你的练习套路中尽量避免使用内置函数。原文链接:https://towardsdatascience.com/5-python-coding-questions-asked-at-faang-59e6cf5ba2a0)
