独家 | 在Python编程面试前需要学会的10个算法(附代码)
作者:AnBento
翻译:陈超
校对:陈丹
本文长度为3300字,建议阅读10+分钟
本文为大家介绍了最近在Python编程面试中反复出现的10个基础算法问题,并且给出了相应的解答过程。
Photo by Headway on Unsplash
为什么练习算法是关键?
如果你是Python新手,并且打算面试顶尖公司(FAANG),听着,你需要从现在开始就好好练习算法。
不要像我第一次练习算法时那么天真。尽管我认为从早到晚死磕算法很有趣,但是我从来没有花过太多时间练习,甚至更少花时间去使用快捷、高效的解决方法。在我看来,我认为花一天的时间解决算法问题有点太傻了,而且在实际工作环境中很不适用,而且长期来看这也不会给我带来多大的收益。
“知道如何解决算法问题将会成为你在找工作过程中极有竞争力的优势”
好吧……我错了(至少在某种程度上来说):我仍然认为花费太多时间在算法上而不注重其他技能远远不能让你找到理想的工作,但是我知道作为一个程序员,复杂的问题总会自己出现在日常的工作当中,因此大公司不得不找到一个标准化的流程来收集应聘者在问题解决和细节技能关注的见解。这意味着知道如何解决算法问题将会成为在找工作的你的一个竞争优势,甚至不那么出名的公司也倾向于采纳这样的评估方法。
那里有一整个世界
在我开始更专注地解决算法问题之后不久,我发现有很多资源可供练习、学习最有效的策略以及为面试做好充足的心理准备,比如以下几个例子:
HackerRank:
https://www.hackerrank.com/interview/interview-preparation-kit
LeetCode :
https://leetcode.com/explore/interview/card/top-interview-questions-easy/
CodingBat :
https://codingbat.com/python
GeeksForGeeks:
https://www.geeksforgeeks.org/python-programming-language/?ref=leftbar
练习顶级的面试问题,这些网站通常会按照公司对算法问题进行分组,并且把人们分享详细的面试经验总结的活跃博客嵌入进去,有时也会提供模拟面试问题作为优选计划(premium plans)的一部分。
例如,LeetCode可以通过特定的公司以及频率筛选顶尖的面试问题。你也可以选择自己觉得合适的试题难度(简单、中等、困难):
来源:https://leetcode.com/problemset/all/
那里有上百道不同的算法问题,这意味着,要做到能够识别出常见的模式并在10分钟以内得出有效的解决方法需要大量的时间和投入。
“如果你一开始感觉到解决这些算法问题很困难千万不要灰心丧气,这是很正常的事。”
如果你一开始感觉到解决这些算法问题很困难千万不要灰心丧气,这是很正常的事。即使有经验的Python程序员在没有充分的训练之前,也会感觉到有很多算法题很难解。
如果你的面试不如预期并且你才刚开始刷题,也不要沮丧。有很多人会刷好几个月的算法题,并且做有规律地复习才能最终拿下一场面试。
为了在你的练习过程中帮到你,我精选了10个在电话面试过程中反复出现的算法(主要是关于字符串操作和数组)。这些问题的难度大都比较容易,所以这会是一个很好的开始。
请注意我给出的每个问题的解答仅仅是许多潜在解决方法的其中之一,通常是一个蛮力解法(“Brute Force”)。因此请自主选择你自己的解法,尝试在运行时间和所用内存之间找到适当的平衡。
字符串处理
1. 整数逆位输出
# Given an integer, return the integer with reversed digits.
# Note: The integer could be either positive or negative.def solution(x):string = str(x)if string[0] == '-':return int('-'+string[:0:-1])else:return int(string[::-1])print(solution(-231))
print(solution(345))
Output:
-132
543
这是一个预热算法,将帮助您练习切片技巧。实际上,唯一棘手的问题是确保您考虑整数为负数的情况。我已经看到此问题以许多不同的方式呈现,但这通常有更复杂的要求。
2. 平均单词长度
# For a given sentence, return the average word length.
# Note: Remember to remove punctuation first.sentence1 = "Hi all, my name is Tom...I am originally from Australia."
sentence2 = "I need to work very hard to learn more about algorithms in Python!"def solution(sentence):for p in "!?',;.":sentence = sentence.replace(p, '')words = sentence.split()return round(sum(len(word) for word in words)/len(words),2)print(solution(sentence1))
print(solution(sentence2))
Output:
4.2
4.08
要求使用字符串来进行一些简单计算的算法非常常见,因此你需要对.replace()和.split()这些方法非常熟悉,这样才能帮助你删除不想要的字符并且创建单词长度容易计算和求和的单词表。
3. 添加字符串
# Given two non-negative integers num1 and num2 represented as string, return the sum of num1 and num2.
# You must not use any built-in BigInteger library or convert the inputs to integer directly.#Notes:
#Both num1 and num2 contains only digits 0-9.
#Both num1 and num2 does not contain any leading zero.num1 = '364'
num2 = '1836'# Approach 1:
def solution(num1,num2):eval(num1) + eval(num2)return str(eval(num1) + eval(num2))print(solution(num1,num2))#Approach2
#Given a string of length one, the ord() function returns an integer representing the Unicode code point of the character
#when the argument is a unicode object, or the value of the byte when the argument is an 8-bit string.def solution(num1, num2):n1, n2 = 0, 0m1, m2 = 10**(len(num1)-1), 10**(len(num2)-1)for i in num1:n1 += (ord(i) - ord("0")) * m1 m1 = m1//10 for i in num2:n2 += (ord(i) - ord("0")) * m2m2 = m2//10return str(n1 + n2)
print(solution(num1, num2))
Output:
2200
2200
我发现两种方法同样好用:第一种胜在简洁和直观地使用eval()方法对基于字符串的输入进行动态评估,而第二种胜在ord()功能的巧妙使用,来通过其字符的Unicode编码将两个字符串重构成实际的数字。如果你真的要选择其中的一种,我倾向于选择第二种,因为它第一眼看上去更复杂,但是通常在解决需要更高级的字符串处理和计算的“中等”和“困难”算法问题当中非常好用。
4. 第一个不同的字母
# Given a string, find the first non-repeating character in it and return its index.
# If it doesn't exist, return -1. # Note: all the input strings are already lowercase.#Approach 1
def solution(s):frequency = {}for i in s:if i not in frequency:frequency[i] = 1else:frequency[i] +=1for i in range(len(s)):if frequency[s[i]] == 1:return ireturn -1print(solution('alphabet'))
print(solution('barbados'))
print(solution('crunchy'))print('###')#Approach 2
import collectionsdef solution(s):# build hash map : character and how often it appearscount = collections.Counter(s) # <-- gives back a dictionary with words occurrence count #Counter({'l': 1, 'e': 3, 't': 1, 'c': 1, 'o': 1, 'd': 1})# find the indexfor idx, ch in enumerate(s):if count[ch] == 1:return idx return -1print(solution('alphabet'))
print(solution('barbados'))
print(solution('crunchy'))
Output:
1
2
1
###
1
2
1
在这种情况下,也是有两种潜在的解决方法,我猜测如果你是算法小白,第一种看起来更熟悉,因为它是从空字典开始构建的简单计数器。
然而理解第二种方法将会从长期来看帮助你更多,这是因为在这个算法当中我简单地使用了collection.Counter(s)代替创建字符计数器,并且用enumerate(s)代替了range(len(s)),enumerate(s)是一个可以帮助你更好地识别索引地址的函数。
5. 有效回文
# Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.
# The string will only contain lowercase characters a-z.s = 'radkar'
def solution(s):for i in range(len(s)):t = s[:i] + s[i+1:]if t == t[::-1]: return Truereturn s == s[::-1]solution(s)
Output:
True
“回文数列”问题是一个经典问题,你可能会在很多不同场景都见到它。任务是检查通过移除最多一个字符之后,字符串是否与它的逆向字符串相匹配。当s=’radkar’时,函数返回True,因为除去’k’之后,我们获得单词’radar’是一个回文序列。
数组
6. 单调数组
# Given an array of integers, determine whether the array is monotonic or not.
A = [6, 5, 4, 4]
B = [1,1,1,3,3,4,3,2,4,2]
C = [1,1,2,3,7]def solution(nums): return (all(nums[i] <= nums[i + 1] for i in range(len(nums) - 1)) or all(nums[i] >= nums[i + 1] for i in range(len(nums) - 1))) print(solution(A))
print(solution(B))
print(solution(C))
Output:
True
False
True
这是另外一个常见的问题,以上提供的解决方法也是非常漂亮的,因为可以用一行解决。当且仅当某一数组单调递增或单调递减时才被称为单调数组,为了评估它,以上算法利用了all()函数,当所有可迭代项为真,则返回True,否则返回FALSE。如果迭代对象是空,all()函数也会返回True。
7. 移动零
#Given an array nums, write a function to move all zeroes to the end of it while maintaining the relative order of
#the non-zero elements.array1 = [0,1,0,3,12]
array2 = [1,7,0,0,8,0,10,12,0,4]def solution(nums):for i in nums:if 0 in nums:nums.remove(0)nums.append(0)return numssolution(array1)
solution(array2)
Output:
[1, 3, 12, 0, 0]
[1, 7, 8, 10, 12, 4, 0, 0, 0, 0]
当你在处理数组的时候,.remove()和.append()的方法是“黄金组合”。在这个问题当中,我用他们首先将属于原始数组的零移除,然后把移出的零填到同一个数组的末尾。
8. 填空
# Given an array containing None values fill in the None values with most recent
# non None value in the array
array1 = [1,None,2,3,None,None,5,None]def solution(array):valid = 0 res = [] for i in nums: if i is not None: res.append(i)valid = ielse:res.append(valid)return ressolution(array1)
Output:
[1, 1, 2, 3, 3, 3, 5, 5]
在真实面试过程中,我有两次都被问到这个问题。这两次都需要包括边界情况(我在这里为了简化省略了)。在论文当中,这是一个易于创建的算法,但是你需要在脑海中有一个清晰的概念,你到底希望通过这个for循环和if语句实现什么,并且可以轻松地使用None值。
9. 匹配和失匹配单词
#Given two sentences, return an array that has the words that appear in one sentence and not
#the other and an array with the words in common. sentence1 = 'We are really pleased to meet you in our city'
sentence2 = 'The city was hit by a really heavy storm'def solution(sentence1, sentence2):set1 = set(sentence1.split())set2 = set(sentence2.split())return sorted(list(set1^set2)), sorted(list(set1&set2)) # ^ A.symmetric_difference(B), & A.interp(B)print(solution(sentence1, sentence2))
Output:
(['The','We','a','are','by','heavy','hit','in','meet','our','pleased','storm','to','was','you'],['city', 'really'])
这个问题非常直观,但是该算法利用了一些非常常见的set操作,例如set(), interp() or &以及symmetric_difference() or ^这些方法都会让你的解题过程更漂亮。如果你是第一次见到它们,请查看一下这个网址:https://www.programiz.com/python-programming/set
10. 质数数据
# Given k numbers which are less than n, return the set of prime number among them
# Note: The task is to write a program to print all Prime numbers in an Interval.
# Definition: A prime number is a natural number greater than 1 that has no positive divisors other than 1 and itself. n = 35
def solution(n):prime_nums = []for num in range(n):if num > 1: # all prime numbers are greater than 1for i in range(2, num):if (num % i) == 0: # if the modulus == 0 is means that the number can be divided by a number preceding itbreakelse:prime_nums.append(num)return prime_nums
solution(n)
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
我想用另外一个经典问题来结束这一部分。如果你熟悉质数的定义和模运算,就可以轻而易举地找到遍历range(n)的解法。
结论
本文当中我分享了10个在编程面试当中常被问到的Python算法。如果你正在准备一家知名技术公司的面试,这篇文章对你熟悉常见算法模式并且循序渐进到更复杂问题来说,是一个好的开始。顺便请注意本文当中的练习(及其解决方案)只是针对Leetcode和GeekforGeeks上存在的问题稍微做了重新解释。在这个领域我还远非达得到一个专家的水平,因此我呈现的解决方法仅仅是指示性的。
原文标题:
10 Algorithms To Solve Before your Python Coding Interview
原文链接:
https://towardsdatascience.com/10-algorithms-to-solve-before-your-python-coding-interview-feb74fb9bc27
编辑:黄继彦
校对:龚力
译者简介
陈超,北京大学应用心理硕士在读。本科曾混迹于计算机专业,后又在心理学的道路上不懈求索。越来越发现数据分析和编程已然成为了两门必修的生存技能,因此在日常生活中尽一切努力更好地去接触和了解相关知识,但前路漫漫,我仍在路上。
翻译组招募信息
工作内容:需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。
你能得到:定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。
其他福利:来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。
点击文末“阅读原文”加入数据派团队~
转载须知
如需转载,请在开篇显著位置注明作者和出处(转自:数据派ID:DatapiTHU),并在文章结尾放置数据派醒目二维码。有原创标识文章,请发送【文章名称-待授权公众号名称及ID】至联系邮箱,申请白名单授权并按要求编辑。
发布后请将链接反馈至联系邮箱(见下方)。未经许可的转载以及改编者,我们将依法追究其法律责任。
点击“阅读原文”拥抱组织
独家 | 在Python编程面试前需要学会的10个算法(附代码)相关推荐
- java面试算法总结_java编程面试过程中常见的10大算法概念汇总
以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java的角度看问题,包含下面的这些概念: ...
- 鸿钧老祖 数据结构笔记01:编程面试过程中常见的10大算法(java)
以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java的角度看问题,包含下面的这些概念: ...
- python100个必背知识-python编程面试中必考的知识点,数据类型全解,笔记超全面...
原标题:python编程面试中必考的知识点,数据类型全解,笔记超全面 python作为一门高级编程语言,它的定位是优雅.明确和简单.阅读Python编写的代码感觉像在阅读英语一样,这让使用者可以专注于 ...
- Python编程,使用turtle画出漂亮的雪花--完整代码绘画实现洁白的雪绒花~~
Python编程,使用turtle画出漂亮的雪花--完整代码实现洁白的雪绒花~~ Python中turtle库,可以方便的让你实现各种各样的功能.简单易用,有的时候能够创作出,你想像不到的漂亮图案.今 ...
- 树莓派python实例_使用Python实现树莓派WiFi断线自动重连实例(附代码)
实现 WiFi 断线自动重连,原理是用 Python 监测网络是否断线,如果断线则重启网络服务.接下来给大家分享实现代码,需要的朋友参考下 1.Python 代码 autowifi.py,放在 /ho ...
- python编程计算前30项的和_Python 程序员需要知道的 30 个技巧
如果你让一个 Python 程序员说一下 Python 的优势,他会说简洁以及高可读是最有影响力的优势.为证明上述两点,在这个 Python 教程里,我们将聊聊许多基本的 Python 建议和技巧. ...
- Python编程快速上手,让繁琐工作自动化(附下载)
今天给大家分享一份Python程序员的圣经--<Python编程快速上手:让繁琐工作自动化>.这是本面向实践的Python编程实用指南. 目录 第一章 Python基础 第二章 控制流 第 ...
- python快速上手 让繁琐工作自动化 英文版_入门python:《Python编程快速上手让繁琐工作自动化》中英文PDF+代码...
入门推荐学习<python编程快速上手>前6章是python的基础知识,通俗易懂地讲解基础,初学者容易犯错的地方,都会指出来.从第三章开始,每章都有一个实践项目,用来巩固前面所学的知识. ...
- 树莓派python编程小车_树莓派小车教程(三)——软件代码
原标题:树莓派小车教程(三)--软件代码 树莓派小车教程(三)--软件代码 2017-07-07 琳小豆 HelloWorld少儿编程 树莓派小车教程 (三) 在上一次教程中,我们已经完成了硬件连接. ...
最新文章
- 你需要知道的高性能并发框架Disruptor原理
- 决战春招!算法工程师面试问题及资料超详细合集(算法岗面经/代码实战/网课/竞赛等)...
- EIGRP 实验2: 邻居关系
- ceph-deploy出错UnableToResolveError Unable to resolve host
- 【逆水寒三周年】大型MMO项目UI管理的价值与责任
- 常用Flex IOC框架比较分析【转载】
- spring boot 尚桂谷学习笔记07 嵌入式容器 ---Web
- SqlServer中使用游标进行双重遍历
- 射频识别技术漫谈(17)——射频卡中数据的存储形式
- BiShop 模式识别与机器学习
- php通过函数怎么禁止百度蜘蛛抓取,怎么屏蔽百度蜘蛛(Baiduspider)抓取网站
- MySQL 从入门到实践,万字详解!
- java面试-多线程常见面试题
- 【PythonPlanet】二手房产成交数据分析
- filters过滤器的简单使用
- Altium Designer 网表导入常见问题 网表导入教程 同步原理图与PCB
- ajax的get/post请求及其封装,以及ajaxHTTP状态码是啥子意思
- 克里斯蒂安贝尔_“蝙蝠侠”克里斯蒂安贝尔将加入漫威电影宇宙饰演大反派
- 杰理之GPIO汇总【篇】
- 命令模式实现电视遥控器
热门文章
- java out.write ie8_整理一下最近遇到的ie8兼容问题
- 阿里云成香港最大公共云服务商,获评最佳公共云服务商
- SSI —— 开源的人类行为分析解决方案
- 《深入理解Hadoop(原书第2版)》——1.3大数据的编程模型
- CocoStudio 1.3和1.4.1导入Flash文件注意事项(转载并有修改)
- 利用JS将页面指定部分存为HTML页
- 计算机组成原理小论文参考文献,急!···跪求.《计算机组成原理》--论文--一篇...
- 线程VS进程,多线程VS多进程,并行VS并发,单核cpuVS多核cpu
- pandas.set_index()
- 王孟源:中国要崛起,基础科研需要“讲实话